//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
///
//==================================================================

#ifndef GXY_H
#define GXY_H

#include "psys.h"
#include "gxy_base.h"
#include "gxy_font.h"
#include "gxy_sprite.h"
#include "gxy_context.h"
#include "texture_base.h"

//==================================================================
namespace GXY {

//==================================================================
// high-level draw functions
//==================================================================
// used by DrawRectFrame()
enum
{
	FRAME_MASK_LEFT		= 1,
	FRAME_MASK_TOP		= 2,
	FRAME_MASK_RIGHT	= 4,
	FRAME_MASK_BOTTOM	= 8,
	FRAME_MASK_ALL		= (FRAME_MASK_LEFT|FRAME_MASK_TOP|FRAME_MASK_RIGHT|FRAME_MASK_BOTTOM),
};

//==================================================================
void SetScale( float sx, float sy );
void SetRotation( float angle );

// Set a color for the drawing
// minimum one color, maximum 4
void SetColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0 );

void SetColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1 );

void SetColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1,
				   u_char r2, u_char g2, u_char b2, u_char a2 );

void SetColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1,
				   u_char r2, u_char g2, u_char b2, u_char a2,
				   u_char r3, u_char g3, u_char b3, u_char a3 );

void SetColorRGBA( const u_char *rgba0p,
				   const u_char *rgba1p=0,
				   const u_char *rgba2p=0,
				   const u_char *rgba3p=0 );

inline void GetColorRGBA( u_char *out_rgba0p )
{
	out_rgba0p[0] = _ctxp->_sys_state._colverts[0][0];
	out_rgba0p[1] = _ctxp->_sys_state._colverts[0][1];
	out_rgba0p[2] = _ctxp->_sys_state._colverts[0][2];
	out_rgba0p[3] = _ctxp->_sys_state._colverts[0][3];
}

void SetColorRGB( u_char r0, u_char g0, u_char b0 );

void SetColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1 );

void SetColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1,
				  u_char r2, u_char g2, u_char b2 );

void SetColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1,
				  u_char r2, u_char g2, u_char b2,
				  u_char r3, u_char g3, u_char b3 );

void SetColorRGB( const u_char *rgb0p,
				  const u_char *rgb1p=0,
				  const u_char *rgb2p=0,
				  const u_char *rgb3p=0 );

// sprites and text are rendered like this:
//		rgb0-----rgb1
//		 |        |
//		 |        |
//		rgb3-----rgb2

// Set a color for the drawing
// minimum one color, maximum 4
void SetOutColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0 );

void SetOutColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1 );

void SetOutColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1,
				   u_char r2, u_char g2, u_char b2, u_char a2 );

void SetOutColorRGBA( u_char r0, u_char g0, u_char b0, u_char a0,
				   u_char r1, u_char g1, u_char b1, u_char a1,
				   u_char r2, u_char g2, u_char b2, u_char a2,
				   u_char r3, u_char g3, u_char b3, u_char a3 );

void SetOutColorRGBA( const u_char *rgba0p,
				   const u_char *rgba1p=0,
				   const u_char *rgba2p=0,
				   const u_char *rgba3p=0 );

void SetOutColorRGB( u_char r0, u_char g0, u_char b0 );

void SetOutColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1 );

void SetOutColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1,
				  u_char r2, u_char g2, u_char b2 );

void SetOutColorRGB( u_char r0, u_char g0, u_char b0,
				  u_char r1, u_char g1, u_char b1,
				  u_char r2, u_char g2, u_char b2,
				  u_char r3, u_char g3, u_char b3 );

void SetOutColorRGB( const u_char *rgb0p,
				  const u_char *rgb1p=0,
				  const u_char *rgb2p=0,
				  const u_char *rgb3p=0 );


// Draw a sprite specified by sitem, at the position (x,y)
// with the scale and rotation and color given by
// SetScale(), SetRotation() and glt_draw_color?()
void DrawSprite( Sprite *spritep, float x, float y, float size_sca_x=1.0f, float size_sca_y=1.0f );
void DrawSpriteCalcSize( Sprite *spritep, float *wp, float *hp, float size_sca_x=1.0f, float size_sca_y=1.0f );
void DrawSpriteRect( Sprite *spritep, float x, float y, float w, float h );
void DrawSpriteRepeat( Sprite *spritep, float x, float y, float w, float h, float size_sca_x=1.0f, float size_sca_y=1.0f );

// Draw a rect
void DrawRectFill( float x, float y, float w, float h );
void DrawRectFill( const float xywh[4] );
void DrawRectFrame( float x, float y, float w, float h, float tickness, u_int mask=FRAME_MASK_ALL );

void DrawRoundRectFill( float x, float y, float w, float h, float radius,
							 bool hard1=false, bool hard2=false, bool hard3=false, bool hard4=false );

void DrawRoundRectFrame( float x, float y, float w, float h, float radius, float thickness,
							  const u_char incol[4], const u_char midcol[4], const u_char outcol[4],
							  u_int mask=FRAME_MASK_ALL );

// Draw a line
void DrawLine( float x1, float y1, float x2, float y2 );
void DrawLine( const float xy1[2], const float xy2[2] );

//==================================================================
// low-level draw functions
//==================================================================
enum PrimType
{
	PRIM_QUADS = 0,	//< quads (one quad every 4 vertices)
	PRIM_TRIGS,		//< triangles (one triangle every 3 vertices)
	PRIM_TRIFAN,	//< triangles' fan
	PRIM_TRISTRIP,	//< triangles' strip
	PRIM_LINES,		//< lines (a new line every 2 vertices)
	PRIM_LINESTRIP,	//< line strip (2 vertices for the first line, then one line for every additional vertex)
	PRIM_TYPES_N,	
};

//==================================================================
// set the material to use for next primitives
void SelectTexture( TextureBase *texturep );
// Begin primitive rendering
void PrimBegin( PrimType prim_type );
// end primitive rendering
void PrimEnd();

// set a vertex color (must be done before SetVertPos())
/*
void SetVertRGB( u_char r, u_char g, u_char b );
void SetVertRGB( const u_char *rgb );
void SetVertRGBA( u_char r, u_char g, u_char b, u_char a );
void SetVertRGBA( const u_char *argbp );
*/
//==================================================================
__inline void SetVertRGB( u_char r, u_char g, u_char b )
{
	//PASSERT( _listp != 0 );
	_ctxp->_glt_cur_col[0] = r;
	_ctxp->_glt_cur_col[1] = g;
	_ctxp->_glt_cur_col[2] = b;
	_ctxp->_glt_cur_col[3] = 255;
}
//==================================================================
__inline void SetVertRGB( const u_char *rgbp )
{
	//PASSERT( _listp != 0 );
	_ctxp->_glt_cur_col[0] = rgbp[0];
	_ctxp->_glt_cur_col[1] = rgbp[1];
	_ctxp->_glt_cur_col[2] = rgbp[2];
	_ctxp->_glt_cur_col[3] = 255;
}
//==================================================================
__inline void SetVertRGBA( u_char r, u_char g, u_char b, u_char a )
{
	//PASSERT( _listp != 0 );
	_ctxp->_glt_cur_col[0] = r;
	_ctxp->_glt_cur_col[1] = g;
	_ctxp->_glt_cur_col[2] = b;
	_ctxp->_glt_cur_col[3] = a;
}
//==================================================================
__inline void SetVertRGBA( const u_char *rgbap )
{
	//PASSERT( _listp != 0 );
	_ctxp->_glt_cur_col[0] = rgbap[0];
	_ctxp->_glt_cur_col[1] = rgbap[1];
	_ctxp->_glt_cur_col[2] = rgbap[2];
	_ctxp->_glt_cur_col[3] = rgbap[3];
}


// set a vertex texture (must be done before SetVertPos())
void SetVertTxcoord( float s, float t );
void SetVertTxcoord( const float *stp );

// set a vertex with the position specified by the call
// and color and texture coordinates specified by
// SetVertRGBA() and SetVertTxcoord()
void SetVertPos( float x, float y );
void SetVertPos( const float *xyp );

//==================================================================
inline void SetBlend( PSYSGFX::BasicBlend blendtype )
{
	_ctxp->_sys_state._blend = blendtype;
}

// Render everything
void Flush();

//==================================================================
};

#endif
